// NOTE:this is an client javascript for hot module reload.
// do not use it for production environment!

const es = new EventSource("__ES_PATH__");
es.addEventListener("open", (_) => {
  console.log("tserve is connect dev server.");
});

es.addEventListener("error", (ev) => {
  console.error("sorry, es encounter an error");
  console.error(ev);
});

es.addEventListener("css-update", function (ev) {
  const data = JSON.parse(ev.data);
  const id = data.id;
  let links = document.querySelectorAll(`link[href*='${id}']`);
  // if length is not undefined
  if (data.length !== undefined) {
    if (links.length === 0) {
      for (let i = 0; i < data.length; i++) {
        const link = document.createElement("link");
        link.href = `${id}?type=style&index=${i}`;
        link.rel = "stylesheet";
        document.head.appendChild(link);
      }
    } else {
      for (let i = 0; i < links.length; i++) {
        const link = links[i];
        link.href += `&t=${i}`;
      }
    }
  } else {
    if (links.length) {
      links.item(0).href = `${id}?t=${Date.now()}`;
    } else {
      const link = document.createElement("link");
      link.rel = "stylesheet";
      link.href = id;
    }
  }
});

es.addEventListener("module-update", function (ev) {
  const data = JSON.parse(ev.data);
  const id = data.id;
  // reimport module
  console.log(`update ${id}`);

  if (id.endWidth(".js")) {
    window.location.reload();
  } else {
    import(`${id}?t=${Date.now()}`).then((val) => {
      // NOTE: after loaded updated code and rerun hot code
      // to use it to transform code
      console.log(`updated ${id}`);
      console.debug("[tserve debug]", val);
    });
  }
});

// TODO:debug for hot code inject.
// because vue scopeid is not as same as file id and front end has no hash generaotr to generate hash code.
// es.addEventListener('vue-update', function (ev) {
//   const data = JSON.parse(ev.data)
//   const id = data.id
//   import(`${id}?t=${Date.now()}`)
//     .then(m => vueLoad(data._scopeId, m.default))
//     .catch(e => {
//       console.error(e)
//     })
// })

// for some imoprt css transform to javascript
// @param {string} id css id
// @param {string} code code of css
export function updateStyle(id, code) {
  let style = document.getElementById(id);
  if (style === null) {
    style = document.createElement("style");
    style.id = id;
    document.head.appendChild(style);
  }
  style.textContent = code;
}

// handle error
window.addEventListener("error", function (e) {
  console.error(e);
});
